package com.magenta.maxoptra.gis.datasources;

import com.magenta.maxoptra.gis.datasources.jaxb.ColumnType;
import com.magenta.maxoptra.gis.datasources.jaxb.DataSourceType;
import com.magenta.maxoptra.gis.datasources.jaxb.TableType;
import com.magenta.maxoptra.gis.datasources.jaxb.TablesType;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;

/**
 * @author Sergey Grachev
 */
public final class GisDataSource extends BaseClass {
    private final static GisTable NULL_TABLE = new GisTable();

    private final String jndi;
    private final String url;
    private final Map<String, GisTable> tables = new HashMap<String, GisTable>(0);

    GisDataSource() {
        this.isNull = true;
        this.name = this.jndi = this.url = null;
    }

    GisDataSource(final DataSourceType dataSource) {
        this.name = dataSource.getName();
        this.jndi = dataSource.getJndi();
        this.url = dataSource.getUrl();
        TablesType dataSourceTables = dataSource.getTables();
        if ( dataSourceTables == null ) {
        	return;
        }
		for (final TableType tableType : dataSourceTables.getTable()) {
            tables.put(tableType.getAlias(), new GisTable(tableType));
        }
    }

    /**
     * Internal name of data source
     */
    public String name() {
        return name;
    }

    /**
     * Full JNDI name of data source
     */
    public String jndi() {
        return jndi;
    }

    /**
     * Optional Url of data source, can be represent as http url:
     * <pre>
     * http://localhost:5000/matrix?loc={0},{1}(&{n},{n+1})*
     * </pre>
     */
    public String url() {
        return url;
    }

    /**
     * Lookup data source using NDI name
     * @throws NamingException
     */
    public DataSource lookup() throws NamingException {
        return isNull() ? null : (DataSource) new InitialContext().lookup(jndi);
    }

    /**
     * Get table by internal name
     */
    public GisTable table(final String alias) {
        return tables.containsKey(alias) ? tables.get(alias) : NULL_TABLE;
    }

    @Override
    public String toString() {
        return "GisDataSource{" +
                "name='" + name + '\'' +
                ", jndi='" + jndi + '\'' +
                ", tables=" + tables +
                '}';
    }
}
